#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <wels/codec_api.h>
#include <assert.h>

#define WELS_LOG_DEFAULT 0

#define ASSERT_EQ
#define ASSERT_TRUE

/*
 * out put encode data
 */
void writeEncode(int ofd, SFrameBSInfo &info)
{
	for (int i = 0; i < info.iLayerNum; ++i) {
		PLayerBSInfo plinfo = &info.sLayerInfo[i];
		unsigned char *data = plinfo->pBsBuf;
		for (int j = 0; j < plinfo->iNalCount; ++j) {
			int data_len = plinfo->pNalLengthInByte[j];
			write(ofd, data, data_len);
			data += data_len;
		}
	}
}

int
main(int argc, char *argv[])
{
	int width = 176;
	int height = 144;
	int framerate = 25;
//open only error & waring log
	int g_LevelSetting = 2;
	ISVCEncoder *encoder_;
	int rv = WelsCreateSVCEncoder (&encoder_);
	ASSERT_EQ (0, rv);
	ASSERT_TRUE (encoder_ != NULL);

	SEncParamBase param;
 	memset (&param, 0, sizeof (SEncParamBase));
//	param.iUsageType = SCREEN_CONTENT_REAL_TIME;
	param.fMaxFrameRate = framerate;
	param.iPicWidth = width;
	param.iPicHeight = height;
	param.iTargetBitrate = 5000000;
	encoder_->Initialize (&param);

	encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
 	int videoFormat = videoFormatI420;
	encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);

	int frameSize = width * height * 3 / 2;
	unsigned char *buf = (unsigned char *)malloc(frameSize);

	SFrameBSInfo info;
	memset (&info, 0, sizeof (SFrameBSInfo));
	SSourcePicture pic;
	memset (&pic, 0, sizeof (SSourcePicture));
//	init input picture
	pic.iPicWidth = width;
	pic.iPicHeight = height;
	pic.iColorFormat = videoFormatI420;
	pic.iStride[0] = pic.iPicWidth;
	pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
	pic.pData[0] = buf;
	pic.pData[1] = pic.pData[0] + width * height;
	pic.pData[2] = pic.pData[1] + (width * height >> 2);
	int fd = open(argv[1], O_RDONLY);
	int ofd = open(argv[2], O_WRONLY | O_CREAT, 0644);


    rv = encoder_->EncodeParameterSets (&info);
	if (rv == 0)
		writeEncode(ofd, info);

	for(;read(fd, buf, frameSize) == frameSize;) {
		//prepare input data
		rv = encoder_->EncodeFrame (&pic, &info);
		if (rv != 0 
			|| info.eFrameType == videoFrameTypeSkip)
			continue;
		writeEncode(ofd, info);
	}
	for(;! encoder_->EncodeFrame(NULL, &info);)
		if (info.eFrameType != videoFrameTypeSkip)
			writeEncode(ofd, info);

	if (encoder_) {
		encoder_->Uninitialize();
		WelsDestroySVCEncoder (encoder_);
	}
	free(buf);
	close(fd);
	close(ofd);

	return 0;
}

